﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Teigha.DatabaseServices;
using Teigha.Geometry;

namespace ExportCADFiles
{
    public class CADTools
    {
        public static void zoom_extents_handler(Database database)
        {
            using (DBObject pVpObj = active_viewport_id(database).GetObject(OpenMode.ForWrite))
            {
                // using protocol extensions we handle PS and MS viewports in the same manner 使用协议扩展，我们以相同的方式处理PS和MS视图
                AbstractViewportData pAVD = new AbstractViewportData(pVpObj);
                pAVD.GsView = new Teigha.GraphicsSystem.View();
                Teigha.GraphicsSystem.View pView = pAVD.GsView;
                if (pView != null)
                {
                    // do actual zooming - change GS view 实际缩放-改变GS视图
                    zoom_extents(database,pView, pVpObj);
                    // save changes to database 保存对数据库的更改
                    pAVD.SetView(pView);
                    pAVD.Dispose();
                    pVpObj.Dispose();
                }
            }
        }
        static bool isZoom = false;
        static void zoom_extents(Database database,Teigha.GraphicsSystem.View pView, DBObject pVpObj)
        {
            try
            {
                if (!isZoom)
                {
                    isZoom = true;
                    if (pView == null)
                        return;
                    // here protocol extension is used again, that provides some helpful functions
                    //这里再次使用了协议扩展，提供了一些有用的功能

                    using (AbstractViewPE pVpPE = new AbstractViewPE(pView))
                    {
                        //pView.Update();
                        BoundBlock3d bbox = new BoundBlock3d();
                        bool bBboxValid = pVpPE.GetViewExtents(bbox);

                        // paper space overall view 纸张空间全景
                        if (pVpObj is Teigha.DatabaseServices.Viewport && ((Teigha.DatabaseServices.Viewport)pVpObj).Number == 1)
                        {
                            if (!bBboxValid || !(bbox.GetMinimumPoint().X < bbox.GetMaximumPoint().X && bbox.GetMinimumPoint().Y < bbox.GetMaximumPoint().Y))
                            {
                                bBboxValid = get_layout_extents(database, pView, ref bbox);
                            }
                        }

                        else if (!bBboxValid) // model space viewport 模型空间窗口
                        {
                            bBboxValid = get_layout_extents(database, pView, ref bbox);
                        }

                        if (!bBboxValid)
                        {
                            // set to somewhat reasonable (e.g. paper size) 设置为比较合理(例如纸张大小)
                            if (database.Measurement == MeasurementValue.Metric)
                            {
                                bbox.Set(Point3d.Origin, new Point3d(297.0, 210.0, 0.0)); // set to papersize ISO A4 (portrait)
                            }
                            else
                            {
                                bbox.Set(Point3d.Origin, new Point3d(11.0, 8.5, 0.0)); // ANSI A (8.50 x 11.00) (landscape)
                            }
                            bbox.TransformBy(pView.ViewingMatrix);
                        }

                        pVpPE.ZoomExtents(bbox);
                    }
                }
            }
            catch
            {

            }
            finally
            {
                isZoom = false;
            }
        }
        static bool get_layout_extents(Database db, Teigha.GraphicsSystem.View pView, ref BoundBlock3d bbox)
        {
            BlockTable bt = (BlockTable)db.BlockTableId.GetObject(OpenMode.ForRead);
            BlockTableRecord pSpace = (BlockTableRecord)bt[BlockTableRecord.PaperSpace].GetObject(OpenMode.ForRead);
            Layout pLayout = (Layout)pSpace.LayoutId.GetObject(OpenMode.ForRead);
            Extents3d ext = new Extents3d();
            if (pLayout.GetViewports().Count > 0)
            {
                bool bOverall = true;
                foreach (ObjectId id in pLayout.GetViewports())
                {
                    if (bOverall)
                    {
                        bOverall = false;
                        continue;
                    }

                    Teigha.DatabaseServices.Viewport pVp = (Teigha.DatabaseServices.Viewport)id.GetObject(OpenMode.ForRead);
                }
                ext.TransformBy(pView.ViewingMatrix);
                bbox.Set(ext.MinPoint, ext.MaxPoint);
            }
            else
            {
                ext = pLayout.Extents;
            }
            bbox.Set(ext.MinPoint, ext.MaxPoint);
            return ext.MinPoint != ext.MaxPoint;
        }
        private static ObjectId active_viewport_id(Database database)
        {

            if (database.TileMode)
            {
                return database.CurrentViewportTableRecordId;
            }
            else
            {
                using (BlockTableRecord paperBTR = (BlockTableRecord)database.CurrentSpaceId.GetObject(OpenMode.ForRead))
                {
                    Layout l = (Layout)paperBTR.LayoutId.GetObject(OpenMode.ForRead);
                    return l.CurrentViewportId;
                }
            }

        }
    }
}
